package controllers

import (
	"blogDemo/models"
	"encoding/json"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"github.com/gomodule/redigo/redis"
	"sort"
	"strconv"
	"time"
)

type BlogController struct {
	baseController
}

// @Title	GetBlog
// @Description Query a blog
// @Param	id 	path	int true	"Query a blog by ID"
// @Success 201 Query a blog successfully
// @Failure 403 Failed to query a blog
// @router /GetBlog/:id [get]
func (b *BlogController) GetBlog() {
	Id, err := b.GetInt(":id")
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"后台获取数据失败")
		b.ServeJSON()
	}
	var blog = models.Blog{Id: Id}
	b.o.Read(&blog)
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"后台操作数据库失败")
		b.ServeJSON()
	}
	// 增加该博客的浏览量
	blogViews :=  "blogViews:" + strconv.Itoa(blog.Id)
	do, err := b.pool.Do("EXISTS", blogViews)
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"链接redis数据库失败")
		b.ServeJSON()
	}
	if do == int64(1) {
		b.pool.Do("incr",blogViews)
	} else {
		b.pool.Do("set",blogViews,1)
	}
	// 增加该日博客浏览量
	viewsInADay := "blogViews:"+ time.Unix(time.Now().Unix(), 0).String()[:10]
	doADay, err := b.pool.Do("EXISTS", viewsInADay)
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"链接redis数据库失败")
		b.ServeJSON()
	}
	if doADay == int64(1) {
		b.pool.Do("incr",viewsInADay)
	} else {
		b.pool.Do("set",viewsInADay,1)
	}
	// 增加博客总的浏览量
	allBlogViews :=  "allBlogViews"
	doAll, err := b.pool.Do("EXISTS", allBlogViews)
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"链接redis数据库失败")
		b.ServeJSON()
	}
	if doAll == int64(1) {
		b.pool.Do("incr",allBlogViews)
	} else {
		b.pool.Do("set",allBlogViews,1)
	}
	b.Data["json"] = models.GetRevaOk(blog)
	b.ServeJSON()
}

// @Title AddBlog
// @Description Add blog information
// @Param body	body	models.Blog true	"Add blog information"
// @Success 201 Add a blog successfully
// @Failure 403 Failed to add a blog
// @router /AddBlog/ [post]
func (b *BlogController) AddBlog()  {
	var blog models.Blog
	json.Unmarshal(b.Ctx.Input.RequestBody, &blog)
	_, err := b.o.Insert(&blog)
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"后台操作数据库失败")
		b.ServeJSON()
	}
	b.Data["json"] = models.GetRevaOk(blog)
	b.ServeJSON()
}

// @Title DeleteBlog
// @Description	Delete the blog
// @Param id path	int	true "Delete blog by ID"
// @Success 201	Succeeded in deleting the blog by ID
// @Failure 403 Failed to delete blog by ID
// @router /DeleteBlog/:id [delete]
func (b *BlogController) DeleteBlog() {
	Id, err := b.GetInt(":id")
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"后台获取数据失败")
		b.ServeJSON()
	}
	i, err := b.o.Delete(&models.Blog{Id: Id})
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"后台操作数据库失败")
		b.ServeJSON()
	}
	b.Data["json"] = models.GetRevaOk("成功删除"+ strconv.Itoa(int(i)) + "条数据")
	b.ServeJSON()
}

// @Title UpdateBlog
// @Description Update the blog
// @Param body body		models.Blog	true "Update the blog"
// @Success 201	Update blog successfully
// @Failure 403 Failed to update blog
// @router /UpdateBlog/ [put]
func (b *BlogController) UpdateBlog()  {
	var blog models.Blog
	json.Unmarshal(b.Ctx.Input.RequestBody, &blog)
	_, err := b.o.Update(&blog)
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"后台操作数据库失败")
		b.ServeJSON()
	}
	b.Data["json"] = models.GetRevaOk(blog)
	b.ServeJSON()
}

// @Title	GetAllBlog
// @Description Query all blogs
// @Success 201 Query all blogs successfully
// @Failure 403 Failed to query all blogs
// @router /getAllBlog/ [get]
func (b *BlogController) GetAllBlog() {
	var blogs []models.Blog
	blog := models.Blog{}
	_, err := b.o.QueryTable(blog.TableName()).All(&blogs)
	if err != nil {
		beego.Error(err)
		b.Data["json"] = models.GetRevaErr(err,"获取全部内容失败")
		b.ServeJSON()
	}
	b.Data["json"] = models.GetRevaOk(blogs)
	b.ServeJSON()
}

// @Title	GetAllArticle
// @Description Query all articles
// @Success 201 Query all articles successfully
// @Failure 403 Failed to query all articles
// @router /getAllArticle/ [get]
func (b *BlogController) GetAllArticle() {
	var blogs []models.Blog
	blog := models.Blog{}
	_, err := b.o.QueryTable(blog.TableName()).Filter("blog_state",0).All(&blogs)
	if err != nil {
		beego.Error(err)
		b.Data["json"] = models.GetRevaErr(err,"获取全部文章失败")
		b.ServeJSON()
	}
	b.Data["json"] = models.GetRevaOk(blogs)
	b.ServeJSON()
}

// @Title	GetAllDraft
// @Description Query all drafts
// @Success 201 Query all drafts successfully
// @Failure 403 Failed to query all drafts
// @router /getAllDraft/ [get]
func (b *BlogController) GetAllDraft() {
	var blogs []models.Blog
	blog := models.Blog{}
	_, err := b.o.QueryTable(blog.TableName()).Filter("blog_state",1).All(&blogs)
	if err != nil {
		beego.Error(err)
		b.Data["json"] = models.GetRevaErr(err,"获取全部草稿失败")
		b.ServeJSON()
	}
	b.Data["json"] = models.GetRevaOk(blogs)
	b.ServeJSON()
}

// @Title GetBlogByLabel
// @Description Articles obtained by labels
// @Param	type 	path	string true	"Articles obtained by type"
// @Success 201 Success of articles obtained through tags
// @Failure 403 The article obtained by the label failed
// @router /getBlogByLabel/:label [get]
func (b *BlogController) GetBlogByLabel() {
	label := b.GetString(":label")
	var blogs []models.Blog
	blog := models.Blog{}
	_, err := b.o.QueryTable(blog.TableName()).Filter("blog_label",label).Filter("blog_state",0).All(&blogs)
	if err != nil {
		beego.Error(err)
		b.Data["json"] = models.GetRevaErr(err,"根据标签获取全部文章失败")
		b.ServeJSON()
	}
	b.Data["json"] = models.GetRevaOk(blogs)
	b.ServeJSON()
}

// @Title GetBlogByType
// @Description Articles obtained by type
// @Param	type 	path	string true	"Articles obtained by type"
// @Success 201 Success of articles obtained through type
// @Failure 403 The article obtained by the type failed
// @router /getBlogByType/:type [get]
func (b *BlogController) GetBlogByType() {
	Type := b.GetString(":type")
	var blogs []models.Blog
	blog := models.Blog{}
	beego.Error(Type)
	logs.Info(Type)
	uri := b.Ctx.Request.RequestURI
	beego.Error(uri)
	_, err := b.o.QueryTable(blog.TableName()).Filter("blog_state",0).Filter("blog_type",Type).All(&blogs)
	if err != nil {
		beego.Error(err)
		b.Data["json"] = models.GetRevaErr(err,"根据类型获取全部文章失败")
		b.ServeJSON()
	}
	b.Data["json"] = models.GetRevaOk(blogs)
	b.ServeJSON()
}

// @Title GetAllTypes
// @Description Articles obtained by type
// @Success 201 Success of articles obtained through type
// @Failure 403 The article obtained by the type failed
// @router /getAllTypes/ [get]
func (b *BlogController) GetAllTypes() {
	var types []string
	// 先取出所有文章的分类然后去重
	var blogs []models.Blog
	blog := models.Blog{}
	_, err := b.o.QueryTable(blog.TableName()).Filter("blog_state",0).All(&blogs)
	if err != nil {
		beego.Error(err)
		b.Data["json"] = models.GetRevaErr(err,"获取全部文章失败")
		b.ServeJSON()
	}
	for _, m := range blogs {
		types = append(types, m.BlogType)
	}
	// 去重
	sort.Strings(types)
	n := 0
	if len(types) != 0 {
		for _, s := range types {
			if types[n] == s {
				continue
			} else {
				n++
				types[n] = s
			}
		}
		types = types[:n+1]
	}
	b.Data["json"] = models.GetRevaOk(types)
	b.ServeJSON()
	// select * from 表名 where 范围	选择查询
}

// @Title GetAllLabels
// @Description Articles obtained by type
// @Success 201 Success of articles obtained through type
// @Failure 403 The article obtained by the type failed
// @router /getAllLabels/ [get]
func (b *BlogController) GetAllLabels() {
	var labels []string
	// 先取出所有文章的标签然后去重
	var blogs []models.Blog
	blog := models.Blog{}
	_, err := b.o.QueryTable(blog.TableName()).Filter("blog_state",0).All(&blogs)
	if err != nil {
		beego.Error(err)
		b.Data["json"] = models.GetRevaErr(err,"获取全部文章失败")
		b.ServeJSON()
	}
	for _, m := range blogs {
		labels = append(labels, m.BlogLabel)
	}
	// 去重
	sort.Strings(labels)
	n := 0
	if len(labels) != 0 {
		for _, s := range labels {
			if labels[n] == s {
				continue
			} else {
				n++
				labels[n] = s
			}
		}
		labels = labels[:n+1]
	}
	b.Data["json"] = models.GetRevaOk(labels)
	b.ServeJSON()
	// select * from 表名 where 范围	选择查询
}

// @Title	GetAllBlogViews
// @Description Query all blogViews
// @Success 201 Query all blogViews successfully
// @Failure 403 Failed to query all blogViews
// @router /getAllBlogViews/ [get]
func (b *BlogController) GetAllBlogViews(){
	allBlogViews :=  "allBlogViews"
	doAll, err := b.pool.Do("EXISTS", allBlogViews)
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"链接redis数据库失败")
		b.ServeJSON()
	}
	if doAll == int64(1) {
		i, err := redis.Int(b.pool.Do("Get", allBlogViews))
		if err != nil {
			b.Data["json"] = models.GetRevaErr(err,"非关系型数据库转换类型失败")
			b.ServeJSON()
		}
		b.Data["json"] = models.GetRevaOk(i)
		b.ServeJSON()
	} else {
		b.Data["json"] = models.GetRevaOk(0)
		b.ServeJSON()
	}
}

// @Title	GetBlogViews
// @Description Query a blogView
// @Param	id 	path	int true	"Query a blogView by ID"
// @Success 201 Query a blogView successfully
// @Failure 403 Failed to query a blogView
// @router /getBlogViews/:id [get]
func (b *BlogController) GetBlogViews(){
	Id, err := b.GetInt(":id")
	if err != nil {
		beego.Error("获取参数失败")
		b.Data["json"] = models.GetRevaErr(err,"获取参数失败")
		b.ServeJSON()
	}
	blogViews :=  "blogViews:"+ strconv.Itoa(Id)
	do, err := b.pool.Do("EXISTS", blogViews)
	if err != nil {
		b.Data["json"] = models.GetRevaErr(err,"链接redis数据库失败")
		b.ServeJSON()
	}
	if do == int64(1) {
		i, err := redis.Int(b.pool.Do("get", blogViews))
		if err != nil {
			b.Data["json"] = models.GetRevaErr(err,"非关系型数据库转换类型失败")
			b.ServeJSON()
		}
		b.Data["json"] = models.GetRevaOk(i)
		b.ServeJSON()
	} else {
		b.Data["json"] = models.GetRevaOk(0)
		b.ServeJSON()
	}
}

// @Title	GetViewsInWeek
// @Description Query the number of page views in a week
// @Success 201 Query the number of page views for a week succeeded
// @Failure 403 Failed to query weekly page views
// @router /GetViewsInWeek/ [get]
func (b *BlogController) GetViewsInWeek() {
	m := make(map[string]int)
	sum := 0
	for i := 0; i < 7;i++ {
		viewsInDay := "blogViews:" + time.Unix(time.Now().Unix() - int64(i*86400), 0).String()[:10]
		do, err := b.pool.Do("EXISTS", viewsInDay)
		if err != nil {
			b.Data["json"] = models.GetRevaErr(err, "链接redis数据库失败")
			b.ServeJSON()
		}
		if do == int64(1) {
			num, err := redis.Int(b.pool.Do("get", viewsInDay))
			if err != nil {
				b.Data["json"] = models.GetRevaErr(err, "非关系型数据库转换类型失败")
				b.ServeJSON()
			}
			m[time.Unix(time.Now().Unix() - int64(i*86400), 0).String()[:10]] = num
			sum += num
		} else {
			m[time.Unix(time.Now().Unix() - int64(i*86400), 0).String()[:10]] = 0
		}
	}
	m["sum"] = sum
	b.Data["json"] = models.GetRevaOk(m)
	b.ServeJSON()
}